如何10分钟快速搭建一个高可用的Kubernetes集群。
Key | Value |
---|---|
OS | CentOS 7 |
Docker | 建议 >= 13.1 |
Kubernetes | 1.13.0 |
Kubernetes Master | HA*3 |
Kubernetes etcd | HA*3 |
网络 | flannel |
LB | Nginx或HAProxy |
前置准备
Docker
安装并启动docker,这里不做赘述。
安装包
准备etcd、kubeadm、kubectl、kubelet、kubernetes-cni、cri-tools等安装包。1
wget https://github.com/etcd-io/etcd/releases/download/v3.2.22/etcd-v3.2.22-linux-amd64.tar.gz
1 | vim /etc/yum.repo.d/kubernetes.repo |
1 | yum install --downloadonly --downloaddir ./ kubelet kubeadm kubectl kubernetes-cni cri-tools |
镜像
1 | docker pull k8s.gcr.io/kube-proxy:v1.13.0 |
网络插件
使用部署和运维最简单的flannel。1
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
LB
无论使用哪种LB工具,需要保证以下几点:
- 分配到三个master节点的权重均等。
- 从VIP的6443端口转发到后端的三个master节点的相同端口。
- 从VIP的2379和2380端口转发到后端的三个etcd节点的相同端口。
- 各个master节点之间、master到VIP、node到VIP的网络需畅通。
假设此例中的VIP为10.107.105.241。
节点
假设master节点的IP如下,同时作为etcd集群的节点:
10.107.105.207
10.107.116.238
10.107.116.213
etcd安装步骤
1. 安装etcd
采用yum源安装,使用的版本为3.2.22。1
yum install -y etcd
2. etcd服务配置
对三台etcd节点的etcd服务均设置相同的数据目录。1
vim /lib/systemd/system/etcd.service
1 | [Service] |
3. etcd数据目录
对三台etcd节点,在外部挂载磁盘的/data路径下创建etcd的数据目录,并赋予正确的权限。1
2mkdir -p /data/etcd
chown etcd:etcd
4. etcd详细配置
假设设置10.107.105.207为etcd集群的leader,则将其ETCD_INITIAL_CLUSTER_STATE
设置为"new"
,其他两台设置为"exist"
;同时他们配置相同的ETCD_INITIAL_CLUSTER
和ETCD_INITIAL_CLUSTER_TOKEN
。
如下为leader 10.107.105.207的/etc/etcd/etcd.conf
配置。1
2
3
4
5
6
7
8
9
10
11#[Member]
ETCD_DATA_DIR="/data/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://10.107.105.207:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.107.105.207:2379,http://127.0.0.1:2379"
ETCD_NAME="etcd1"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.107.105.207:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://10.107.105.207:2379,http://127.0.0.1:2379"
ETCD_INITIAL_CLUSTER="etcd1=http://10.107.105.207:2380,etcd2=http://10.107.116.238:2380,etcd3=http://10.107.116.213:2380"
ETCD_INITIAL_CLUSTER_TOKEN="mlss-k8s-etcd"
ETCD_INITIAL_CLUSTER_STATE="new"
如下分别为10.107.116.238及10.107.116.213的/etc/etcd/etcd.conf
配置。1
2
3
4
5
6
7
8
9
10
11#[Member]
ETCD_DATA_DIR="/data/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://10.107.116.238:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.107.116.238:2379,http://127.0.0.1:2379"
ETCD_NAME="etcd2"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.107.116.238:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://10.107.116.238:2379,http://127.0.0.1:2379"
ETCD_INITIAL_CLUSTER="etcd1=http://10.107.105.207:2380,etcd2=http://10.107.116.238:2380,etcd3=http://10.107.116.213:2380"
ETCD_INITIAL_CLUSTER_TOKEN="mlss-k8s-etcd"
ETCD_INITIAL_CLUSTER_STATE="exist"
1 | #[Member] |
4. 启动etcd
至此etcd集群配置完毕,需要将其启动,在leader及另外两台节点上执行如下操作。1
2systemctl daemon-reload
systemctl restart etcd
节点全部启动完毕后,在任意一台机器上验证:1
etcdctl member list
Kubernetes安装步骤
对于集群中的每个master节点,需进行步骤1-6。
1. 关闭swap
1 | swapoff -a |
2. 关闭防火墙
1 | systemctl stop firewalld;systemctl disable firewalld;setenforce 0 |
3. 禁用selinux
1 | vim /etc/selinux/config |
4. 启用bridge-nf
1 | sysctl net.bridge.bridge-nf-call-iptables=1 |
5. cgroup driver设置
理论上,kubelet的cgroup driver与docker的cgroup driver需保持一致。
- 如果在docker的配置中(
/lib/systemd/system/docker.service
或/etc/sysconfig/docker*
或/etc/docker/daemon.json
),设置了native.cgroupdriver=cgroupfs
,则在kubelet的配置中(/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
)设置--cgroup-driver=cgroupfs
。 - 如果docker的
native.cgroupdriver=systemd
,则在kubelet中设置--cgroup-driver=systemd
。
然而在实际中:
- 如果docker中设置了
native.cgroupdriver=cgroupfs
,kubelet不做任何额外配置,节点可以正常启动Kubelet。 - 如果docker中设置了
native.cgroupdriver=systemd
,kubelet不做任何额外配置,节点仍然可以正常启动Kubelet,但/var/lib/kubelet/config.yaml
中显示cgroupDriver: cgroupfs
,说明kubelet默认的cgroup driver为cgroupfs
。
6. 设置启动参数
1 | vim kubeadm.conf |
创建初始化配置文件设置启动参数。
apiServerCertSANs
设置所有master节点的IP、hostname及LB的VIP。controlPlaneEndpoint
设置为<VIP>:6443
,6443为apiserver的默认端口。etcd
设置为external,并填写上述所有etcd节点的IP及2379端口。networking
设置pod子网网段,根据CNI的需求而不同。controllerManagerExtraArgs
及schedulerExtraArgs
设置address
为0.0.0.0
,将其暴露给集群,此设置是出于监控采集controller-manager及scheduler的metrics的考虑。
1 | apiVersion: kubeadm.k8s.io/v1alpha3 |
7. 启动第一个master
在第一台节点上使用该配置启动集群。1
kubeadm init --config kubeadm.conf
记录下最后输出的kubeadm join
命令。
8. 启动其他master
待第一个master节点完成初始化后,将/etc/kubernetes/pki
目录下的所有文件拷贝至其他两个节点的相同目录下。
使用相同的配置依次启动其他两个master。1
kubeadm init --config kubeadm.conf
记录下最后输出的kubeadm join
命令。
9. kubectl
在任意一台master节点上,使用以下命令来给kubectl添加配置。1
2
3mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
使用kubectl get no
验证,应该能看到三台NotReady的master。
10. CNI
这里我们采用flannel作为CNI插件,使用以下命令创建网络组件。1
kubectl apply -f kube-flannel.yml
11. 加入node
步骤7和8生成的join命令格式如下:1
kubeadm join 10.107.105.241:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
三个master节点初始化后的token
是不同的,但discovery-token-ca-cert-hash
是相同的,因此对于node来说,使用任意一台master生成的token来join即可。
常见问题
coredns启动失败
coredns处于CrashLoopBackoff,这是由于coredns的默认配置的问题,执行以下命令即可:1
2
3kubectl -n kube-system get deployment coredns -o yaml | \
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | \
kubectl apply -f -
清理
1. 重置数据
在所有机器上使用kubeadm清理数据。1
2
3kubeadm reset
rm -rf /etc/kubernetes
rm -rf $HOME/.kube
2. 重置网络
在所有机器上需要清理掉CNI网络的相关内容。1
2ifconfig flannel.1 down && ip link delete flannel.1
ifconfig cni0 down && ip link delete cni0
3. 清空etcd
在etcd节点上,直接删除etcd存放的Kubernetes集群数据即可。1
rm -rf /data/etcd/default.etcd